package com.webwork.lims.orders.dao.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.webwork.lims.common.dao.impl.SimpleDao;
import com.webwork.lims.common.dataobject.CtrlerAndTime;
import com.webwork.lims.orders.dao.OrderDao;
import com.webwork.lims.orders.dataobject.Order;
import com.webwork.lims.orders.dataobject.OrderStatus;
import com.webwork.lims.util.ColumnLimit;
import com.webwork.lims.util.DBSimpleSQL;
import com.webwork.lims.util.StrManager;

@Repository
public class OrderDaoImpl extends SimpleDao implements OrderDao {

	public OrderDaoImpl() {
		super();
		this.dbTable = "t_orders";
		dbColumns.clear();
		dbColumns.put("orderId", "ORDER_ID");
		dbColumns.put("sku", "SKU");
		dbColumns.put("amount", "AMOUNT");
		dbColumns.put("zoneId", "ZONE_ID");
		dbColumns.put("address", "ADDRESS");
		dbColumns.put("receiver", "RECEIVER");
		dbColumns.put("phone", "PHONE");
		dbColumns.put("createPerson", "CREATE_PERSON");
		dbColumns.put("createTime", "CREATE_TIME");
		dbColumns.put("verifyPerson", "VERIFY_PERSON");
		dbColumns.put("verifyTime", "VERIFY_TIME");
		dbColumns.put("completePerson", "COMPLETE_PERSON");
		dbColumns.put("completeTime", "COMPLETE_TIME");
		dbColumns.put("status", "STATUS");
		dbColumns.put("transId", "TRANS_ID");
	}
	
	@Override
	public ColumnLimit condition(Object object) {
		if (!(object instanceof Order))
			return new ColumnLimit();
		Order o = (Order) object;
		ColumnLimit ret = new ColumnLimit();
		if (!StrManager.isEmpty(o.getOrderId())) {
			ret.add(dbColumns.get("orderId") + " = ");
		}
		if (!StrManager.isEmpty(o.getReceiver())) {
			ret.add(dbColumns.get("receiver") + " like ");
		}
		if (o.getStatus() != null && o.getStatus() != OrderStatus.NOSET) {
			ret.add(dbColumns.get("status") + " = ");
		}
		if (o.getZoneCode() != 0) {
			ret.add(dbColumns.get("zoneId") + " = ");
		}
		if (!StrManager.isEmpty(o.getQueryTime())) {
			ret.add(dbColumns.get("createTime") + " like ");
		}
		if (!StrManager.isEmpty(o.getTransId())) {
			ret.add(dbColumns.get("transId") + " = ");
		}
		return ret;
	}

	@Override
	public Object[] statement(Object object) {
		Order o = (Order) object;
		List<Object> ret = new ArrayList<Object>();
		if (!StrManager.isEmpty(o.getOrderId())) {
			ret.add(o.getOrderId());
		}
		if (!StrManager.isEmpty(o.getReceiver())) {
			ret.add("%" + o.getReceiver() + "%");
		}
		if (o.getStatus() != null && o.getStatus() != OrderStatus.NOSET) {
			ret.add(o.getStatus().getCode());
		}
		if (o.getZoneCode() != 0) {
			ret.add(o.getZoneCode());
		}
		if (!StrManager.isEmpty(o.getQueryTime())) {
			ret.add("%" + o.getQueryTime() + "%");
		}
		if (!StrManager.isEmpty(o.getTransId())) {
			ret.add(o.getTransId());
		}
		return ret.toArray();
	}

	@Override
	public List<Object> pushObject(Object object) {
		Order o = (Order) object;
		List<Object> objs = new ArrayList<Object>();
		objs.add(o.getOrderId());
		objs.add(o.getSku());
		objs.add(o.getAmount());
		objs.add(o.getZoneCode());
		objs.add(o.getAddress());
		objs.add(o.getReceiver());
		objs.add(o.getPhone());
		objs.add(o.getCreate() == null ? null : o.getCreate().getController());
		objs.add(o.getCreate() == null ? new Date(0) : o.getCreate().getTime());
		objs.add(o.getVerify() == null ? null : o.getVerify().getController());
		objs.add(o.getVerify() == null ? new Date(0) : o.getVerify().getTime());
		objs.add(o.getComplete() == null ? null : o.getComplete().getController());
		objs.add(o.getComplete() == null ? new Date(0) : o.getComplete().getTime());
		objs.add(o.getStatus().getCode());
		objs.add(o.getTransId());
		return objs;
	}

	@Override
	public Object catchObject(Map<String, Object> map) {
		Order ret = new Order();
		ret.setOrderId((String) map.get(dbColumns.get("orderId")));
		ret.setSku((String) map.get(dbColumns.get("sku")));
		ret.setAmount((Integer) map.get(dbColumns.get("amount")));
		ret.setZoneCode((Integer) map.get(dbColumns.get("zoneId")));
		ret.setAddress((String) map.get(dbColumns.get("address")));
		ret.setReceiver((String) map.get(dbColumns.get("receiver")));
		ret.setPhone((String) map.get(dbColumns.get("phone")));
		ret.setCreate(new CtrlerAndTime((String) map.get(dbColumns.get("createPerson")), (Timestamp) map.get(dbColumns.get("createTime"))));
		ret.setVerify(new CtrlerAndTime((String) map.get(dbColumns.get("verifyPerson")), (Timestamp) map.get(dbColumns.get("verifyTime"))));
		ret.setComplete(new CtrlerAndTime((String) map.get(dbColumns.get("completePerson")), (Timestamp) map.get(dbColumns.get("completeTime"))));
		ret.setStatus((Integer) map.get(dbColumns.get("status")));
		ret.setTransId((String) map.get(dbColumns.get("transId")));
		return ret;
	}
	
	@Override
	public void insert(Order o) {
		String sql = DBSimpleSQL.insert(dbTable, dbColumns.size());
		this.getJdbcTemplate().update(sql, this.pushObject(o).toArray());
	}
	
	@Override
	public void update(Order o) {
		ColumnLimit limit = new ColumnLimit();
		limit.add(dbColumns.get("orderId") + " = ");
		String sql = DBSimpleSQL.update(dbTable, dbColumns, limit);
		List<Object> objs = this.pushObject(o);
		objs.add(o.getOrderId());
		this.getJdbcTemplate().update(sql, objs.toArray());
	}

	@Override
	public void delete(String orderId) {
		ColumnLimit limit = new ColumnLimit();
		limit.add(dbColumns.get("orderId") + " = ");
		String sql = DBSimpleSQL.del(dbTable, limit);
		this.getJdbcTemplate().update(sql, orderId);
	}

	@Override
	public List<Order> query(Order o, int page, int size) {
		List<Order> ret = new ArrayList<Order>();
		String sql = DBSimpleSQL.selectAll(dbTable, this.condition(o), page, size);
		List<Map<String, Object>> maps = this.getJdbcTemplate().queryForList(sql, this.statement(o));
		for (Map<String, Object> map : maps) {
			ret.add((Order) this.catchObject(map));
		}
		return ret;
	}

	@Override
	public int count(Order o) {
		String sql = DBSimpleSQL.count(dbTable, this.condition(o));
		return this.getJdbcTemplate().queryForObject(sql, this.statement(o), Integer.class);
	}
	
	@Override
	public Date queryFirstDate() {
		String sql = "SELECT MIN(CREATE_TIME) FROM " + dbTable;
		return this.getJdbcTemplate().queryForObject(sql, Timestamp.class);
	}
	
	@Override
	public List<String> queryAddressByGroup(int zoneCode) {
		List<String> ret = new ArrayList<String>();
		String sql = "select ADDRESS from t_orders where ZONE_ID=" + zoneCode + " GROUP BY ADDRESS";
		List<Map<String, Object>> maps =  this.getJdbcTemplate().queryForList(sql);
		for (Map<String, Object> map : maps) {
			ret.add((String) map.get(dbColumns.get("address")));
		}
		return ret;
	}
	
}
